<template>
  <div class="overflow-hidden w-full h-full bg-gray-100">
    <div class="flex flex-row justify-between items-center px-5 h-16 bg-white">
      <div class="text-base">可视化系统</div>
      <div class="flex items-center space-x-2">
        <span>标题</span>
        <input
          v-model="store.pageConfig.title"
          class="px-2 py-1 text-sm rounded border border-gray-300"
          placeholder="页面标题"
        />
      </div>
      <div class="flex space-x-2">
        <el-button size="small" @click="store.undo" :disabled="!store.canUndo">撤销</el-button>
        <el-button size="small" @click="store.redo" :disabled="!store.canRedo">重做</el-button>
        <el-button type="primary" @click="view">预览页面</el-button>
      </div>
    </div>
    <div class="flex flex-row h-[calc(100vh-4rem)]">
      <!-- 左侧组件面板 -->
      <div class="w-[360px] h-full overflow-hidden bg-white border-t border-gray-200">
        <el-tabs>
          <el-tab-pane label="基础组件">
            <VueDraggable
              v-model="basicComponents"
              :sort="false"
              :group="{
                name: 'components',
                pull: 'clone',
                put: false,
              }"
              @end="onEnd"
              :clone="cloneComponent"
              drag-class=""
              ghost-class=""
            >
              <div
                v-for="item in store.getComponentsByCategory('basic')"
                :key="item.id"
                class="flex justify-center items-center px-2.5 mx-2 mt-3 h-8 text-sm leading-8 text-center text-gray-600 bg-gray-100 rounded cursor-move select-none"
              >
                {{ item.name }}
              </div>
            </VueDraggable>
          </el-tab-pane>
          <el-tab-pane label="表单组件">
            <VueDraggable
              v-model="formComponents"
              :sort="false"
              :group="{
                name: 'components',
                pull: 'clone',
                put: false,
              }"
              @end="onEnd"
              :clone="cloneComponent"
              drag-class=""
              ghost-class=""
            >
              <div
                v-for="item in store.getComponentsByCategory('form')"
                :key="item.id"
                class="flex justify-center items-center px-2.5 mx-2 mt-3 h-8 text-sm leading-8 text-center text-gray-600 bg-gray-100 rounded cursor-move select-none"
              >
                {{ item.name }}
              </div>
            </VueDraggable>
          </el-tab-pane>
        </el-tabs>
      </div>

      <!-- 中间画布区域 -->
      <div ref="targetContent" class="flex-1 p-5 bg-gray-100">
        <div class="overflow-auto w-full h-full bg-white rounded shadow">
          <div class="flex items-center p-2 bg-gray-50 border-b border-gray-200">
            <span class="text-sm text-gray-500">画布</span>
            <div class="flex ml-auto space-x-2">
              <el-button size="small" icon="el-icon-delete" @click="clearCanvas">清空</el-button>
            </div>
          </div>

          <VueDraggable
            v-model="store.previewComponents"
            :group="{
              name: 'previewComponents',
              pull: true,
              put: true,
            }"
            ghost-class=""
            class="min-h-[200px] p-4"
            :animation="150"
            @add="onAdd"
            @update="onUpdate"
          >
            <template #header v-if="store.previewComponents.length === 0">
              <div
                class="flex justify-center items-center h-32 text-gray-400 rounded border-2 border-gray-300 border-dashed"
              >
                <div class="text-center">
                  <i class="mb-2 text-2xl el-icon-plus"></i>
                  <p>从左侧拖入组件</p>
                </div>
              </div>
            </template>

            <template v-for="item in store.previewComponents" :key="item.id">
              <div
                class="relative p-1 my-2 rounded border border-transparent group hover:border-gray-200"
              >
                <div
                  class="flex absolute top-0 right-0 space-x-1 opacity-0 transition-opacity group-hover:opacity-100"
                >
                  <div
                    class="px-1 text-xs text-white bg-blue-500 rounded-bl cursor-move component-drag-handle"
                  >
                    <i class="el-icon-rank"></i>
                  </div>
                  <div
                    class="px-1 text-xs text-white bg-red-500 rounded-bl cursor-pointer"
                    @click.stop="deleteComponent(item.id)"
                  >
                    <i class="el-icon-delete"></i>
                  </div>
                </div>

                <component
                  :is="componentsList[item?.code]"
                  :component="item"
                  @click.stop="selectComponent(item)"
                  :class="{
                    'border-2 !border-blue-500 shadow-md': store.nowComponent.id === item.id,
                  }"
                ></component>
              </div>
            </template>
          </VueDraggable>
        </div>
      </div>

      <!-- 右侧配置面板 -->
      <div class="w-[360px] h-full overflow-auto bg-white border-t border-gray-200">
        <div v-if="store.nowComponent.id" class="p-4">
          <h3 class="pb-2 mb-3 text-base font-medium border-b border-gray-200">组件配置</h3>
          <component :is="componentsList[store?.nowComponent?.set]"></component>
        </div>
        <div v-else class="flex justify-center items-center h-full text-gray-400">
          <p>请选择一个组件进行配置</p>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { shallowRef, ref, onMounted, onUnmounted, watch } from 'vue'
import { nanoid } from 'nanoid'
import { VueDraggable } from 'vue-draggable-plus'
import { useLowCodeStore } from '../store/lowcode'
import { componentRegistry } from '../utils/ComponentRegistry'
import StyleEditor from '../components/StyleEditor/index.vue'

const store = useLowCodeStore()
const basicComponents = ref(store.getComponentsByCategory('basic'))
const formComponents = ref(store.getComponentsByCategory('form'))
// 使用组件注册中心获取组件列表
const componentsList = shallowRef({})

// 初始化组件列表
onMounted(() => {
  // 遍历组件注册表，构建componentsList对象
  const components = componentRegistry.getAll()
  const list = {}

  components.forEach((item) => {
    list[item.code] = item.component
    list[item.set] = item.configComponent
  })

  componentsList.value = list

  // 添加键盘快捷键支持
  document.addEventListener('keydown', handleKeyDown)
})

onUnmounted(() => {
  document.removeEventListener('keydown', handleKeyDown)
})

// 键盘快捷键处理
const handleKeyDown = (e) => {
  // Ctrl+Z: 撤销
  if (e.ctrlKey && e.key === 'z') {
    e.preventDefault()
    store.undo()
  }

  // Ctrl+Y: 重做
  if (e.ctrlKey && e.key === 'y') {
    e.preventDefault()
    store.redo()
  }

  // Delete: 删除选中组件
  if (e.key === 'Delete' && store.nowComponent.id) {
    e.preventDefault()
    deleteComponent(store.nowComponent.id)
  }
}

const selectComponent = (item) => {
  console.log('选中组件', item)
  store.nowComponentsData(item)
}

const deleteComponent = (id) => {
  store.deleteComponent(id)
}

const cloneComponent = (originalItem) => {
  console.log('🐯 ~ cloneComponent ~ originalItem:', originalItem)
  const clonedItem = JSON.parse(JSON.stringify(originalItem))

  // 使用找到的组件默认属性
  const componentDef = componentRegistry.getByCode(originalItem.code)
  if (componentDef && componentDef.defaultProps) {
    clonedItem.props = { ...componentDef.defaultProps }
  }

  clonedItem.id = nanoid()

  return clonedItem
}

const onEnd = (obj) => {
  // 不需要在这里处理组件添加，因为克隆函数和onAdd会处理
}

const onAdd = (event) => {
  console.log('添加组件', event)
  const { newIndex } = event

  // 确保新添加的组件被选中
  if (store.previewComponents.length > 0 && newIndex !== undefined) {
    store.nowComponentsData(store.previewComponents[newIndex])
  }
}

const clearCanvas = () => {
  if (store.previewComponents.length > 0) {
    if (confirm('确定要清空画布吗？')) {
      store.previewComponents = []
      store.nowComponent = {}
      store.addHistory()
    }
  }
}

const view = () => {
  localStorage.setItem(
    'lowcode',
    JSON.stringify({
      components: store.previewComponents,
      pageConfig: store.pageConfig,
    }),
  )
  window.open(location.href.replace('/#/', '/preview/#/'))
}

const onUpdate = (event) => {
  // 更新后记录历史
  store.addHistory()
}
</script>
